Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Global macro with `var'

    Dear Statalisters,

    I am trying to use a global macro that contains a reference to a loop (`var').
    This is the original code:

    Code:
    levelsof country, local(levels) 
    foreach l of local levels {
    foreach var of varlist y1 y2 y3 {
    eststo `var'_`l': reg `var' x1 if country== "`l'"
    }
    }
    foreach var of varlist y1 y2 y3 {
    local graphtitle : variable label `var'
    coefplot (`var'_Argentina \ `var'_Austria \ `var'_Belgium \ `var'_Brazil)
    I want to create a global macro with the names of the models I want Stata to run:

    Code:
    global countries "(`var'_Argentina \ `var'_Austria \ `var'_Belgium \ `var'_Brazil)"
    Next, I use the $ command, where I substitute this text for $countries:

    Code:
    levelsof country, local(levels) 
    foreach l of local levels {
    foreach var of varlist y1 y2 y3 {
    eststo `var'_`l': reg `var' x1 if country== "`l'"
    }
    }
    foreach var of varlist y1 y2 y3 {
    local graphtitle : variable label `var'
    coefplot $countries
    However, Stata seems not to identify the `var' before the country name, and the output is the following one:

    estimation result _Argentina not found
    Is there a way to use a global macro with loop content inside?

    Thanks in advance,
    Marc


  • #2
    global countries "(`var'_Argentina \ `var'_Austria \ `var'_Belgium \ `var'_Brazil)"
    When assigning contents to a global (or local) macro, any macros in the string are expanded, so `var' evaluates to nothing. You can escape this by putting a backslash before a macro expansion to prevent this.
    Code:
    . local countries_doesnt_work "(`var'_Argentina \ `var'_Austria \ `var'_Belgium \ `var'_Brazil)"
    
    . local countries_works "(\`var'_Argentina \ \`var'_Austria \ \`var'_Belgium \ \`var'_Brazil)"
    
    .
    . local var "thisworks"
    
    . di "`countries_doesnt_work'"
    (_Argentina \ _Austria \ _Belgium \ _Brazil)
    
    . di "`countries_works'"
    (thisworks_Argentina \ thisworks_Austria \ thisworks_Belgium \ thisworks_Brazil)
    As an aside, I don't see a need to use a global in your case, you could use a local instead. Using globals is generally discouraged unless absolutely necessary.

    Comment


    • #3
      Thanks Wouter!

      I am using global instead of local because "local" is apparently only useful within the same chunk of code, while I am running several models in different parts of the dofile... I guess this is then the best option, isn't it?

      Best regards,
      Marc

      Comment


      • #4
        "Chunk of code" is not a well-defined term within Stata. A local macro is useful within the same running do-file.

        Now, if you have written your code in the do-file editor window, and then rather than running the entire contents of the window at once, you have run it by selecting a few lines and running them, then selecting the next few lines and running them, and so on, you will have problems.

        Consider the following example. In the do-file editor window, I have a two-line program that I run in its entirety.
        Code:
        . do "/Users/lisowskiw/Downloads/example.do"
        
        . local message Hello, world.
        
        . display "The message is `message'"
        The message is Hello, world.
        
        . 
        end of do-file
        Now I run the same two lines by selecting the first line and running it, then selecting the second line and running it.
        Code:
        . do "/var/folders/xr/lm5ccr996k7dspxs35yqzyt80000gp/T//SD17616.000000"
        
        . local message Hello, world.
        
        . 
        end of do-file
        
        . do "/var/folders/xr/lm5ccr996k7dspxs35yqzyt80000gp/T//SD17616.000000"
        
        . display "The message is `message'"
        The message is 
        
        . 
        end of do-file
        The important thing to keep in mind is that local macros vanish when the do-file within which they were created ends. If you look carefully at the results above, you'll see that when I selected a single line to run, it was copied into a temporary do-file and run, so even though both lines are in the same window in the do-file editor, they are run as separate do-files, and local macro defined in the first line vanishes at the end of that do-file, and is undefined when the second line is run.


        Comment


        • #5
          Thanks William, indeed, local is extremely exclusive and the code vanishes even when running it in different lines.
          Perhaps it could be a good idea (for Stata 17) that stored text in local can be used within the same dofile.

          Comment


          • #6
            the code vanishes even when running it in different lines.
            If you think you're seeing this, you're doing something else wrong, perhaps running code from a do-file editor selectively.

            stored text in local can be used within the same dofile.
            This has been possible ever since local macros were introduced.

            Comment


            • #7
              perhaps running code from a do-file editor selectively.
              Yes, I was meaning exactly this.
              I am running a lot of different models and I do not want to copy the local code before every new model. For this, I understand global macro is more useful.

              Comment


              • #8
                The include command was introduced for those who want to re-use local definitions easily.

                Comment


                • #9
                  In principle, it should be possible to record for each open do-file in the do-editor which local macros are defined, so that e.g. you can run different parts of the do-file sharing the same definitions of some parameters.
                  This would make it easier to test parts of the code without having to copy it in the command window if you want to have common definitions for some things across the do-file.
                  The include command does not help in these situations because the definitions in the included file are still only existing in the context of the selected code if the include command is part of the selected code.

                  What you cannot do at the moment, is to define some local macros at the top of the do-file, and then use these definitions to run some selected code from another part of the do-file.
                  Something like the pseudo-code below is not possible
                  Code:
                  local def1 <some definition>
                  local def2 <some other definition> // run these macros first
                  .... <some other code in between>
                  { // code you want to run using definitions from the top
                  command1 `def1'
                  command2 `def2'
                  command3
                  }
                  At the moment you would need to select the macro definitions and the commands at the same time. However, they might be some 50 or 100 lines apart.

                  Comment


                  • #10
                    I don't particularly like the idea of "partial persistence", which seems to come from other statistical languages. My main reason is that it makes debugging harder because then you need to keep track of which macros persist and which belong to the instance, and worry about whether they will collide.

                    Occasionally when I am doing something like this, I follow the below pattern, which amounts to copying the one -include- line from the top of the do-file, to the block of code which I want to debug. This should not be terribly difficult to do.

                    Code:
                    ------------- contents of _include_.do ----
                    // define all local macros here
                    ------------------ end of _include_.do ----
                    
                    -------------- contents of anaylsis.do ----
                    //top of do file
                    qui include _include_.do
                    
                    ....
                    
                    qui include _include_.do
                    // do something here
                    
                    ....
                    ------------------- end of analysis.do ----

                    Comment


                    • #11
                      Anyone else wanting to do this is up to them, but I have to wonder what this kind of idea implies in terms of

                      1. ease of debugging

                      2. ease of interpreting a log file

                      Comment


                      • #12
                        Originally posted by Nick Cox View Post
                        Anyone else wanting to do this is up to them, but I have to wonder what this kind of idea implies in terms of

                        1. ease of debugging
                        For me, I occasionally want to shortcut a block of code that I know works, so I can test code that still depends on the local macros. It's not intended as a permanent solution, of course, but waiting for some lengthy operations to re-run is not efficient. (Alternatives could be to simply comment out those blocks, or wrap them in an if statement that never evaluates to true.) I could also re-factor my analysis into stand-alone do-files that are then called by a master do-file that runs each piece.

                        Comment


                        • #13
                          I think here some experienced people are asking for something they are sure they will understand but it will make confusion easier for learners and casual users of Stata. Goodness know how often threads hinge here on people -- often not at all new to Stata -- misunderstanding quite what local means (and doesn't mean). Asking in effect for more flexibility, or more ways, in which local macros can be used seems to me the wrong way to go.

                          Still, the issue is naturally not at all convincing me: it is convincing StataCorp.

                          Comment


                          • #14
                            Since I weighed in earlier on this topic, I'm with Nick on this one.

                            But then, very little of my work is lengthy enough to make the wait for it to rerun noticeable, and when it is, I take the opportunity to focus on some other diversion, like Statalist.

                            Comment


                            • #15
                              I believe that there are probably good reasons why the do-editor does not support "partial persistence" of local macros or why this idea was never(?) considered by Stata developers.
                              On the one hand, it would be useful for me in certain situations like Leonardo described them. On the other hand, I see how partially persistent local macros can make things more complicated (to debug) than before.

                              Comment

                              Working...
                              X